<?php

namespace fast;

class DateFormat
{
    /**
     * 根据指定日期获取所在周的起始时间和结束时间
     *
     * @param $date
     * @return array
     */
    public static function getWeeksByDate($date)
    {
        $idx = strftime("%u", strtotime($date));
        return [
            'start' => strftime('%Y-%m-%d', strtotime($date) - ($idx - 1) * 86400),
            'end' => strftime('%Y-%m-%d', strtotime($date) - ($idx - 7) * 86400),
        ];
    }

    /**
     * 根据指定日期获取所在月的起始时间和结束时间
     *
     * @param $date
     * @return array
     */
    public static function getMonthsByDate($date)
    {
        $timestamp = strtotime($date);
        return [
            'start' => date('Y-m-1', $timestamp),
            'end' => date('Y-m-' . date('t', $timestamp), $timestamp)
        ];
    }

    /**
     * 获取指定日期之间的各个周
     *
     * @param $start_date
     * @param $end_date
     * @param string $format
     * @return array
     */
    public static function getWeeks($start_date, $end_date, $format = 'Y-m-d')
    {
        $ranges = [];
        // 检查日期有效性
        static::checkDate([$start_date, $end_date]);
        // 计算各个周的起始时间
        do {
            $weeks = static::getWeeksByDate($start_date);
            $start = static::formatDate($weeks['start'], $format);
            $end = static::formatDate($weeks['end'], $format);
            $ranges[] = [
                'start' => $start,
                'end' => $end,
                'range' => "{$start} ~ {$end}"
            ];
            $start_date = date('Y-m-d', strtotime($start_date . '+7 day'));
        } while ($weeks['end'] < $end_date);
        return $ranges;
    }

    /**
     * 获取指定日期之间的各个月
     *
     * @param $start_date
     * @param $end_date
     * @param $format
     * @return array
     */
    public static function getMonths($start_date, $end_date, $format)
    {
        $ranges = [];
        do {
            $months = static::getMonthsByDate($start_date);
            $start = static::formatDate($months['start'], $format);
            $end = static::formatDate($months['end'], $format);
            $ranges[] = [
                'start' => $start,
                'end' => $end,
                'range' => "{$start} ~ {$end}"
            ];
            $start_date = date('Y-m-d', strtotime($start_date . '+1 month'));
        } while ($months['end'] < $end_date);
        return $ranges;
    }

    /**
     * 截取日期中的月份和日
     *
     * @param $date
     * @param string $format
     * @return bool|false|string
     */
    public static function formatDate($date, $format = 'Y-m-d')
    {
        if (!$date) return false;
        return $format == 'Y-m-d' ? $date : date($format, strtotime($date));
    }

    /**
     * 检查日期的有效性 YYYY-mm-dd
     *
     * @param $dates
     */
    public static function checkDate($dates)
    {
        $invalid_dates = [];
        foreach ($dates as $row) {
            $standard = date('Y-m-d', strtotime($row));
            if ($standard != $row) $invalid_dates[] = $row;
        }
        if (!empty($invalid_dates)) {
            die("invalid date :" . print_r($invalid_dates, true));
        }
    }
}
